/*
 ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1

 * The contents of this file are subject to the Mozilla Public License Version 
 * 1.1 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at 
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Blazing Games Inc. (Billy D. Spelchan) code.
 *
 * The Initial Developer of the Original Code is
 * Blazing Games Inc.
 * Portions created by the Initial Developer are Copyright (C) 1999, 2003, 2005-2006
 * the Initial Developer. All Rights Reserved.
 * 
 * Contributor(s):
 *
 ***** END LICENSE BLOCK *****
 */
package com.blazinggames.urcl.data;

// Java imports
import java.awt.*;

/**
 * A loading screen so that you can give users an idea of how long
 * it is going to be before the game runs. The screen is a fairly
 * nice looking loading screen as I see no reason not to have a
 * nice looking loader, especially since this will be used on many
 * games (60 in the ultimate retro series just to start) so the time
 * spent creating this is worthwhile.
 * 
 * @author Billy D. Spelchan
 * @version OSR1.00
 */
public class LoadingBar
{
// *********************
// ***** VARIABLES *****
// *********************

    // Back Buffer
    protected Image _imgBuf;
    protected Graphics _gImgBuf;
    protected Dimension _imgBufSize;

    // Text and text properties
    protected String _companyText = "Blazing Games Inc.";
    protected Font _companyFont = new Font("Serif", 1, 64);
    protected int _companyY = 120;
    protected String _presentsText = "presents";
    protected Font _presentsFont = new Font("Serif", 0, 32);
    protected int _presentsY = 200;
    protected String _nameText = "Name of Game Here!";
    protected Font _nameFont = new Font("Serif", 1, 64);
    protected int _nameY = 300;
    protected String _messageText = "Please wait loading...";
    protected Font _messageFont = new Font("Serif", 0, 32);
    protected int _messageY = 350;
    protected String _copyrightText = "Copyright " + ((char)169) + "2004 Blazing Games Inc.";
    protected Font _copyrightFont = new Font("Serif", 0, 14);
    protected int _copyrightY = 475;

    // colors
    protected int _grad_end_red = 64;
    protected int _grad_start_red = 128;
    protected int _grad_end_green = 0;
    protected int _grad_start_green = 0;
    protected int _grad_end_blue = 64;
    protected int _grad_start_blue = 128;
    protected Color _textColor = new Color(128,128,0);
    protected Color _outlineColor = Color.yellow;
    protected Color _barOutlineColor = Color.black;
    protected Color _barSolidColor = Color.red;

    // loading bar
    protected Rectangle _barBounds = new Rectangle(70, 400, 500, 40);
    protected int _loadPercent = 0;

    // redraw flag - so that updates are faster
    protected boolean _doFullRender;

// ************************
// ***** CONSTRUCTORs *****
// ************************

    /**
     * creates a new loading bar covering the indicated component with the given name
     *
     * @param c container that will hold loading screen
     * @param name name of the game
    */
    public LoadingBar(Component c, String name)
    {
        _imgBufSize = c.getSize();
        _imgBuf = c.createImage(_imgBufSize.width, _imgBufSize.height);
        _gImgBuf = _imgBuf.getGraphics();
        _gImgBuf.setColor(Color.blue);
        _gImgBuf.fillRect(30,30,_imgBufSize.width-60, _imgBufSize.height-60);
        _nameText = name;
        _doFullRender = true;
    }

// *******************************
// ***** METHODS - RENDERING *****
// *******************************

    /**
     * Paints the loading screen.
     *
     * @param g graphics context to draw the game in
     * @param c container renderer is going into
     */
    public void render(Graphics g, Container c)
    {
        if (_doFullRender)
            renderFull();
        _gImgBuf.setColor(_barOutlineColor);
        _gImgBuf.fillRect(_barBounds.x-2, _barBounds.y-2,
                   _barBounds.width+4, _barBounds.height+4);
        _gImgBuf.setColor(_barSolidColor);
        _gImgBuf.fillRect(_barBounds.x, _barBounds.y,
                   _barBounds.width * _loadPercent / 100, _barBounds.height);
        
        g.drawImage(_imgBuf, 0, 0, c);
    }

    /**
     * do a full render as opposed to just updating the bar.
     * This gets called when text or colors change.
    */
    protected void renderFull()
    {
        _doFullRender = false;
        Color c;
        int w = _imgBufSize.width;
        int h = _imgBufSize.height;
        int rspan = _grad_end_red - _grad_start_red;
        int gspan = _grad_end_green - _grad_start_green;
        int bspan = _grad_end_blue - _grad_start_blue;
        int r,gr,b;
        for (int cntr = 0; cntr < w; ++cntr)
        {
            r = _grad_start_red + cntr * rspan / w;
            gr = _grad_start_green + cntr * gspan / w;
            b = _grad_start_blue + cntr * bspan / w;
            c = new Color(r, gr, b);
            _gImgBuf.setColor(c);
            _gImgBuf.drawLine(cntr, 0, cntr, h);
        }

        int middle = _imgBufSize.width / 2;
        drawCenterOutline(_gImgBuf, _companyFont, _companyText, middle, _companyY);
        drawCenterOutline(_gImgBuf, _presentsFont, _presentsText, middle, _presentsY);
        drawCenterOutline(_gImgBuf, _nameFont, _nameText, middle, _nameY);
        drawCenterOutline(_gImgBuf, _messageFont, _messageText, middle, _messageY);
        drawCenterOutline(_gImgBuf, _copyrightFont, _copyrightText, middle, _copyrightY);
    }

    /**
     * utility funtion for drawing centered text.
     *
     * @param g graphics context to draw text into
     * @param f font to draw text in
     * @param s text to be displayed
     * @param x center x position
     * @param y text baseline
    */
    protected void drawCenterOutline(Graphics g, Font f, String s, int x, int y)
    {
        g.setFont(f);
        FontMetrics fm = g.getFontMetrics();
        int w = fm.stringWidth(s);
        int x1 = x - w/2;
        g.setColor(_outlineColor);
        g.drawString(s, x1-1, y-1);
        g.drawString(s, x1+1, y+1);
        g.setColor(_textColor);
        g.drawString(s, x1, y);        
    }

// *******************************************
// ***** METHODS - SETTING SCREEN VALUES *****
// *******************************************

    /**
     * Sets the company line of the loading screen.
     *
     * @param s Text to use.
     */
    public void setCompany(String s)
    {
        _doFullRender = true;
        _companyText = s;
    }

    /**
     * Sets the company line of the loading screen and the rendering
     * properties to render it.
     *
     * @param s Text to use.
     * @param f Font to render text in.
     * @param y baseline of text.
     */
    public void setCompany(String s, Font f, int y)
    {
        _doFullRender = true;
        _companyText = s;
        _companyFont = f;
        _companyY = y;
    }

    /**
     * Sets the presents line of the loading screen.
     *
     * @param s Text to use.
     */
    public void setPresents(String s)
    {
        _doFullRender = true;
        _presentsText = s;
    }

    /**
     * Sets the presents line of the loading screen and the rendering
     * properties to render it.
     *
     * @param s Text to use.
     * @param f Font to render text in.
     * @param y baseline of text.
     */
    public void setPresents(String s, Font f, int y)
    {
        _doFullRender = true;
        _presentsText = s;
        _presentsFont = f;
        _presentsY = y;
    }
    
    /**
     * Sets the name line of the loading screen.
     *
     * @param s Text to use.
     */
    public void setName(String s)
    {
        _doFullRender = true;
        _nameText = s;
    }

    /**
     * Sets the name line of the loading screen and the rendering
     * properties to render it.
     *
     * @param s Text to use.
     * @param f Font to render text in.
     * @param y baseline of text.
     */
    public void setName(String s, Font f, int y)
    {
        _doFullRender = true;
        _nameText = s;
        _nameFont = f;
        _nameY = y;
    }

    /**
     * Sets the Message line of the loading screen.
     *
     * @param s Text to use.
     */
    public void setMessage(String s)
    {
        _doFullRender = true;
        _messageText = s;
    }

    /**
     * Sets the message line of the loading screen and the rendering
     * properties to render it.
     *
     * @param s Text to use.
     * @param f Font to render text in.
     * @param y baseline of text.
     */
    public void setMessage(String s, Font f, int y)
    {
        _doFullRender = true;
        _messageText = s;
        _messageFont = f;
        _messageY = y;
    }

    /**
     * Sets the Copyright line of the loading screen.
     *
     * @param s Text to use.
     */
    public void setCopyright(String s)
    {
        _doFullRender = true;
        _copyrightText = s;
    }

    /**
     * Sets the copyright line of the loading screen and the rendering
     * properties to render it.
     *
     * @param s Text to use.
     * @param f Font to render text in.
     * @param y baseline of text.
     */
    public void setCopyright(String s, Font f, int y)
    {
        _doFullRender = true;
        _copyrightText = s;
        _copyrightFont = f;
        _copyrightY = y;
    }

    /**
     * Sets the colors to use for the background gradient.
     *
     * @param start Starting color for the background gradient
     * @param end Ending color for the background gradient
    */
    public void setBackground(Color start, Color end)
    {
        _doFullRender = true;
        _grad_start_red = start.getRed();
        _grad_end_red = end.getRed();
        _grad_start_green = start.getGreen();
        _grad_end_green = end.getGreen();
        _grad_start_blue = start.getBlue();
        _grad_end_blue = end.getBlue();
    }

    /**
     * Sets the colors to use for rendering the text. Text is drawn
     * using a text color and an outline color.
     *
     * @param c Main text color
     * @param outline outline color
    */
    public void setTextColor(Color c, Color outline)
    {
        _doFullRender = true;
        _textColor = c;
        _outlineColor = outline;
    }

    /**
     * Sets the size and location of the loading bar
     *
     * @param rect size and location of the loading bar
     */
    public void setBarBounds(Rectangle rect)
    {
        _doFullRender = true;
        _barBounds.setBounds(rect);
    }

    /**
     * Sets the loading bar's outline and fill colors
     *
     * @param c fill color of the bar
     * @param outline outline color of the bar
    */
    public void setBarColor(Color c, Color outline)
    {
        _barSolidColor = c;
        _barOutlineColor = outline;
    }

    /**
     * Sets the position of the loading bar
     *
     * @param n percentage of loading that has been completed
    */
    public void setLoadPercent(int n)
    {
        _loadPercent = n;
    }

    /**
     * returns the position of the loading bar.
     *
     * @return position of the loading bar.
    */
    public int getLoadPercent()
    {
        return _loadPercent;
    }
}
